package com.axialproject.health.exchange.google;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gdata.client.http.AuthSubUtil;
import com.axialproject.health.exchange.EMF;
import com.axialproject.health.exchange.PatientManager;
import com.axialproject.health.exchange.entity.Patient;
import java.io.IOException;
import java.net.URLDecoder;
import java.security.PrivateKey;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class ConfirmServlet extends HttpServlet {

    private static final Logger log = Logger.getLogger(ConfirmServlet.class.getName());

    public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {

        HttpSession session = req.getSession();
        String finishUrl = (String) session.getAttribute("finishUrl");
        Long patientId = (Long) session.getAttribute("patientId");
        Long gpatientId = (Long) session.getAttribute("gpatientId");

        /*
        String sig = req.getParameter("sig");
        // validate sig here
        String finishUrl = req.getParameter("finishUrl");

        Long patientId = Long.parseLong(req.getParameter("patientId"));
        Long gpatientId = Long.parseLong(req.getParameter("gpatientId"));
        */

        EntityManager em = EMF.get().createEntityManager ();
        try {
            Patient patient = PatientManager.getPatientById(em, patientId);
            if (patient == null) {
                log.severe("The patientId is invalid");
                resp.setContentType("text/plain");
                resp.getWriter().println("The patientId is invalid");
                return;
            }

            Patient gpatient = PatientManager.getPatientById(em, gpatientId);
            if (gpatient == null) {
                log.severe("The patientId is invalid");
                resp.setContentType("text/plain");
                resp.getWriter().println("The gpatientId is invalid");
                return;
            }

            String singleUseToken = AuthSubUtil.getTokenFromReply(req.getQueryString());
            PrivateKey privateKey = AuthSubUtil.getPrivateKeyFromKeystore("WEB-INF/classes/ringful.jks", "ringful", "health-exchange", "ringful");
            log.info("We got the private key: " + privateKey.toString());
            String sessionToken = AuthSubUtil.exchangeForSessionToken(URLDecoder.decode(singleUseToken, "UTF-8"), privateKey);
            // String sessionToken = AuthSubUtil.exchangeForSessionToken(URLDecoder.decode(singleUseToken, "UTF-8"), null);

            UserService userService = UserServiceFactory.getUserService();
            User user = userService.getCurrentUser();
            if (user == null) {
                throw new Exception ("This servlet must be invoked after a successful Google login!");
            }

            /*
            Patient gpatient = PatientManager.getPatientByUsernameAppName(em, user.getEmail(), "google");
            if (gpatient == null) {
                throw new Exception ("Did not find Google account. It does not seem to have gone through the after_login step.");
            } else {
                gpatient.setToken(sessionToken);
                PatientManager.linkPatientIds(em, patientId, gpatient.getId());
            }
            */

            gpatient.setToken(sessionToken);
            PatientManager.linkPatientIds(em, patientId, gpatient.getId());

            if (finishUrl != null && !"".equals(finishUrl)) {
                if (finishUrl.contains("?")) {
                    resp.sendRedirect(finishUrl + "&success=1");
                } else {
                    resp.sendRedirect(finishUrl + "?success=1");
                }
            } else {
                resp.setContentType("text/plain");
                resp.getWriter().println("Success!");
            }

            // HealthService healthService = new HealthService("ringful-health--v1.0");
            // healthService.setAuthSubToken(sessionToken, null);

        } catch (Exception e) {
            log.log (Level.SEVERE, e.getMessage(), e);
            if (finishUrl != null && !"".equals(finishUrl)) {
                if (finishUrl.contains("?")) {
                    resp.sendRedirect(finishUrl + "&success=0");
                } else {
                    resp.sendRedirect(finishUrl + "?success=0");
                }
            } else {
                resp.setContentType("text/plain");
                resp.getWriter().println("There is a problem!");
            }
        } finally {
            em.close ();
        }

    }
}